package com.cmb.lk50.sink.db;

import com.cmb.lk50.pojo.AbstractLog;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 为每个AbstractLog的子类自定义持久到到jdbc的PreparedStatement
 * <p>
 * Author       : 蒋俊钊 80256973
 * Date         : 2020/8/26
 * Copyright    (C) ChinaMerchantsBank
 */
public class StatementGenerator{

    private Map<Class<? extends AbstractLog>, LogMapper<? extends AbstractLog>> map = new ConcurrentHashMap<>();

    // 通过类型得到PreparedStatement
    <T extends AbstractLog> PreparedStatement getPsByType(Connection connection, T log) throws SQLException {
        LogMapper<T> logMapper = (LogMapper<T>) map.get(log.getClass());
        if (logMapper == null) {
            throw new RuntimeException("未配置[" + log.getClass() + "]对应的LogMapper");
        }
        PreparedStatement preparedStatement = connection.prepareStatement(logMapper.getSql());
        logMapper.customer(preparedStatement, log);
        return preparedStatement;
    }

    // 自动配置时添加
    public void addMapper(LogMapper<? extends AbstractLog> logMapper) {
        Type[] genericInterfaces = logMapper.getClass().getGenericInterfaces();
        Type[] types = ((ParameterizedType) genericInterfaces[0]).getActualTypeArguments();
        map.put((Class<? extends AbstractLog>) types[0], logMapper);
    }

    // 每个子类注入Spring上下文中成为Bean
    public interface LogMapper<T extends AbstractLog> {
        void customer(PreparedStatement preparedStatement, T log) throws SQLException;
        String getSql();
    }

}
